package ch.zhaw.cctd.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.zhaw.cctd.domain.DomainFacade;
import ch.zhaw.cctd.logic.event.ChatEvent;
import ch.zhaw.cctd.logic.event.ChatEventListener;

/**
 * GUI-Aufbau des Chats mit Implementation des ChatListeners.
 * 
 * @author Lukas Spirig
 * 
 */
public class ChatGUI extends JPanel implements ActionListener, KeyListener, ChatEventListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 8476599979277876464L;
	private static final Logger LOG = LoggerFactory.getLogger(ChatGUI.class);

	private JButton send = new JButton("Send");
	private JTextField line;
	private JScrollPane sp;
	private JEditorPane area;
	private ArrayList<String> messages = new ArrayList<String>();
	private String chatContent;
	private int index = 0;

	public ChatGUI() {

		LOG.trace("New Chat Gui");

		this.setLayout(new BorderLayout());
		messages.add("");

		send.addActionListener(this);
		sp = new JScrollPane();

		sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		sp.getVerticalScrollBar().setUnitIncrement(30);
		sp.getVerticalScrollBar().setBlockIncrement(80);
		sp.setPreferredSize(new Dimension(this.getWidth(), 100));
		line = new JTextField();
		line.addKeyListener(this);
		area = new JEditorPane();
		area.setContentType("text/html");
		area.setEditable(false);
		sp.setViewportView(area);
		
		chatContent = "";

		JPanel footer = new JPanel(new BorderLayout());
		footer.add(line, BorderLayout.CENTER);
		footer.add(send, BorderLayout.LINE_END);

		add(sp, BorderLayout.CENTER);
		add(footer, BorderLayout.PAGE_END);
		try {
			UnicastRemoteObject.exportObject(this);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Wird aufgerufen, wenn der Spieler eine neue Nachricht schreibt
	 */
	private void sendMessage() {
		LOG.trace("New Message");
		String message = line.getText();
		line.setText("");

		if (DomainFacade.sendChatMessage(message)) {
			if (!message.equals(messages.get(messages.size() - 1))) {
				messages.add(message);
				index = messages.size();
			}
		} else {
			// Error case:
			addMessage("Error", "Server not Reachable");
		}

		LOG.trace("Chat Are Text is on Client side: {}", area.getText());
		LOG.trace("Message Sent");
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(send)) {
			LOG.trace("Chat Action");
			sendMessage();
			LOG.trace("Chat Action finished");
		}
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		if (arg0.getSource().equals(line)) {
			if (arg0.getKeyCode() == KeyEvent.VK_ENTER && !line.getText().equals("")) {
				sendMessage();
			} else if (arg0.getKeyCode() == KeyEvent.VK_ESCAPE) {
				line.setText("");
				index = messages.size();
			} else if (arg0.getKeyCode() == KeyEvent.VK_UP) {
				if (index > 1)
					line.setText(messages.get(--index));
				else
					line.setText(messages.get(1));
			} else if (arg0.getKeyCode() == KeyEvent.VK_DOWN) {
				if (index < messages.size() - 1)
					line.setText(messages.get(++index));
				else
					line.setText("");
			}
		}
	}

	/**
	 * Wird aufgerufen wenn ein anderer Spieler eine Nachricht schreibt
	 */
	@Override
	public void onMessage(ChatEvent e) throws RemoteException {
		LOG.trace("New Chat Message Received from: {} Text:{} ", e.getOriginUsername(), e.getMessage());
		addMessage(e.getOriginUsername(), e.getMessage());
		LOG.trace("Chat Frame content is:  {}", area.getText());
	}

	/**
	 * Fügt eine Nachricht hinzu und scrollt ganz nach unten
	 * 
	 * @param originUsername
	 * @param message
	 */
	public void addMessage(String originUsername, String message) {
		chatContent += "\n<span>" + originUsername + ": " + message+"</span><br/>";
		area.setText("<html>"+ chatContent +"</html>");
		area.getCaret().setDot(area.getDocument().getLength());
	}

	public void addSystemMessage(String message) {
		chatContent += "\n<span style=\"color:#f00;\">" + message+"</span><br/>";
		area.setText("<html>"+ chatContent +"</html>");
		area.getCaret().setDot(area.getDocument().getLength());
	}

	public void keyPressed(KeyEvent arg0) {
	}

	public void keyTyped(KeyEvent arg0) {
	}
}
